/*
 * Copyright (c) 2015 Razeware LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import CoreData
import UIKit

class DeviceDetailTableViewController: UITableViewController {
    var device: Device?
    var coreDataStack: CoreDataStack!

    @IBOutlet var nameTextField: UITextField!
    @IBOutlet var deviceTypeTextField: UITextField!
    @IBOutlet var deviceOwnerLabel: UILabel!
    @IBOutlet var deviceIdentifierTextField: UITextField!
    @IBOutlet var purchaseDateTextField: UITextField!
    @IBOutlet var imageView: UIImageView!

    private let datePicker = UIDatePicker()
    private var selectedDate: NSDate?
    private lazy var dateFormatter: DateFormatter = {
        let df = DateFormatter()
        df.timeStyle = .none
        df.dateStyle = .medium

        return df
    }()

    private let deviceTypePicker = UIPickerView()
    private var deviceTypes = [DeviceType]()
    private var selectedDeviceType: DeviceType?

    override func viewDidLoad() {
        super.viewDidLoad()

        datePicker.addTarget(self, action: #selector(datePickerValueChanged), for: .valueChanged)
        datePicker.datePickerMode = .date
        purchaseDateTextField.inputView = datePicker

        loadDeviceTypes()
        deviceTypePicker.delegate = self
        deviceTypePicker.dataSource = self
        deviceTypeTextField.inputView = deviceTypePicker
    }

    func loadDeviceTypes() {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "DeviceType")
        fetchRequest.sortDescriptors = [
            NSSortDescriptor(key: "name", ascending: true)
        ]

        do {
            if let results = try coreDataStack.managedObjectContext.fetch(fetchRequest) as? [DeviceType] {
                deviceTypes = results
            }
        } catch {
            fatalError("There was an error fetching the list of device types!")
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if let device = device {
            nameTextField.text = device.name
            deviceTypeTextField.text = device.deviceType?.name
            deviceIdentifierTextField.text = device.deviceID
            imageView.image = device.image

            if let owner = device.owner {
                deviceOwnerLabel.text = "Device owner: \(owner.name)"
            } else {
                deviceOwnerLabel.text = "Set device owner"
            }

            if let deviceType = device.deviceType {
                selectedDeviceType = deviceType

                for (index, oneDeviceType) in deviceTypes.enumerated() {
                    if deviceType == oneDeviceType {
                        deviceTypePicker.selectRow(index, inComponent: 0, animated: false)
                        break
                    }
                }
            }

            if let purchaseDate = device.purchaseDate {
                selectedDate = purchaseDate
                datePicker.date = purchaseDate as Date
                purchaseDateTextField.text = dateFormatter.string(from: purchaseDate as Date)
            }
        }
    }

    override func viewWillDisappear(_ animated: Bool) {
        if let device = device, let name = nameTextField.text {
            device.name = name
            device.deviceType = selectedDeviceType
            device.deviceID = deviceIdentifierTextField.text
            device.purchaseDate = selectedDate
            device.image = imageView.image
        } else if device == nil {
            if let name = nameTextField.text,
                let deviceType = deviceTypeTextField.text, let entity = NSEntityDescription.entity(forEntityName: "Device", in: coreDataStack.managedObjectContext), !name.isEmpty, !deviceType.isEmpty {
                device = Device(entity: entity, insertInto: coreDataStack.managedObjectContext)
                device?.name = name
                device?.deviceType = selectedDeviceType
                device?.deviceID = deviceIdentifierTextField.text
                device?.purchaseDate = selectedDate
                device?.image = imageView.image
            }
        }

        let startTime = CFAbsoluteTimeGetCurrent()

        coreDataStack.saveMainContext()

        let endTime = CFAbsoluteTimeGetCurrent()
        let elapsedTime = (endTime - startTime) * 1000
        print("Saving the context took \(elapsedTime) ms")
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.section == 1, indexPath.row == 0 {
            if let personPicker = storyboard?.instantiateViewController(withIdentifier: "People") as? PeopleTableViewController {
//                personPicker.coreDataStack = coreDataStack

                // more personPicker setup code here
                personPicker.pickerDelegate = self
                personPicker.selectedPerson = device?.owner

                navigationController?.pushViewController(personPicker, animated: true)
            }
        } else if indexPath.section == 2, indexPath.row == 0 {
    let sheet = UIAlertController(title: "Device Image", message: nil, preferredStyle: .actionSheet)

    sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) -> Void in
      }))

    if imageView.image != nil {
        sheet.addAction(UIAlertAction(title: "Remove current image", style: .destructive, handler: { (_) -> Void in

            DispatchQueue.main.async {
                self.imageView.image = nil
            }
        }))
    }

    sheet.addAction(UIAlertAction(title: "Select image from library", style: .default, handler: { (_) -> Void in
        let picker = UIImagePickerController()
        picker.sourceType = .photoLibrary
        picker.delegate = self

        self.present(picker, animated: true, completion: nil)
      }))

    present(sheet, animated: true, completion: nil)
}

        tableView.deselectRow(at: indexPath as IndexPath, animated: true)
    }

    @objc func datePickerValueChanged(datePicker: UIDatePicker) {
        purchaseDateTextField.text = dateFormatter.string(from: datePicker.date)
        selectedDate = dateFormatter.date(from: purchaseDateTextField.text!) as NSDate?
    }
}

extension DeviceDetailTableViewController: UIPickerViewDelegate {
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return deviceTypes[row].name
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        selectedDeviceType = deviceTypes[row]
        deviceTypeTextField.text = selectedDeviceType?.name
    }
}

extension DeviceDetailTableViewController: UIPickerViewDataSource {
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return deviceTypes.count
    }
}

extension DeviceDetailTableViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        DispatchQueue.main.async {
            if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                self.imageView.image = image
            }
        }
        dismiss(animated: true, completion: nil)
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        dismiss(animated: true, completion: nil)
    }
}

extension DeviceDetailTableViewController: PersonPickerDelegate {
    func didSelectPerson(person: Person) {
        device?.owner = person
        coreDataStack.saveMainContext()
    }
}
